#pragma once

#if (defined(WIN32) || defined(_WIN32)) && defined(_MSC_VER)

#include								<windows.h>

#define MEMORY_START						0x401000
#define MAX_VALID_NICKNAME_ADRESSES			0x5A
#define MAX_REPEATED_NICKS_ADRESSES			0x59
#define MAX_NICKNAME_LENGTH_ADRESSES		0xA

unsigned char ValidNickName_Addresses[MAX_VALID_NICKNAME_ADRESSES] =
{
	0x8B, 0x4C, 0x24, 0x04, 0x8A, 0x01, 0x84, 0xC0, 0x74, 0x4A, 0x8D, 0x9B, 0x00, 0x00, 0x00, 0x00,
	0x3C, 0x30, 0x7C, 0x04, 0x3C, 0x39, 0x7E, 0x34, 0x3C, 0x41, 0x7C, 0x04, 0x3C, 0x5A, 0x7E, 0x2C,
	0x3C, 0x61, 0x7C, 0x04, 0x3C, 0x7A, 0x7E, 0x24, 0x3C, 0x5D, 0x74, 0x20, 0x3C, 0x5B, 0x74, 0x1C,
	0x3C, 0x5F, 0x74, 0x18, 0x3C, 0x24, 0x74, 0x14, 0x3C, 0x3D, 0x74, 0x10, 0x3C, 0x28, 0x74, 0x0C,
	0x3C, 0x29, 0x74, 0x08, 0x3C, 0x40, 0x74, 0x04, 0x3C, 0x2E, 0x75, 0x0B, 0x8A, 0x41, 0x01, 0x41,
	0x84, 0xC0, 0x75, 0xBC, 0x32, 0xC0, 0xC3, 0xB0, 0x01, 0xC3
};

unsigned char RepeatedNicks_Addresses[MAX_REPEATED_NICKS_ADRESSES] =
{
	/*
		// 0.3C R5
		53 8B 5C 24 08 56 57 8B  F9 33 F6 EB 03 8D 49 00
		66 81 FE F4 01 73 26 0F  B7 C6 8B 8C 87 68 EA 00
		00 85 C9 74 18 6B C0 19  8D 84 38 08 FA 00 00 53
		50 E8 09 8E 02 00 83 C4  08 85 C0 74 11 46 81 FE
		F4 01 00 00 75 CA 5F 5E  33 C0 5B C2 04 00 5F 5E
		B8 01 00 00 00 5B C2 04  00
	
		// 0.3.7-R2-1
		53 8B 5C 24 08 56 57 8B  F9 33 F6 EB 03 8D 49 00
		66 81 FE E8 03 73 26 0F  B7 C6 8B 8C 87 FC 49 02
		00 85 C9 74 18 6B C0 19  8D 84 38 3C 69 02 00 53
		50 E8 39 4C 03 00 83 C4  08 85 C0 74 11 46 81 FE
		E8 03 00 00 75 CA 5F 5E  33 C0 5B C2 04 00 5F 5E
		B8 01 00 00 00 5B C2 04  00
	*/

	// There is some bytes, which another in some SA:MP versions.
	// That's why we set this bytes to NULL. And in 'CheckMemmory' function we set include_null = false;

	0x53, 0x8B, 0x5C, 0x24, 0x08, 0x56, 0x57, 0x8B, 0xF9, 0x33, 0xF6, 0xEB, 0x03, 0x8D, 0x49, 0x00,
	0x66, 0x81, 0xFE, NULL, NULL, 0x73, 0x26, 0x0F, 0xB7, 0xC6, 0x8B, 0x8C, 0x87, NULL, NULL, NULL,
	0x00, 0x85, 0xC9, 0x74, 0x18, 0x6B, 0xC0, 0x19, 0x8D, 0x84, 0x38, NULL, NULL, NULL, 0x00, 0x53,
	0x50, 0xE8, NULL, NULL, NULL, 0x00, 0x83, 0xC4, 0x08, 0x85, 0xC0, 0x74, 0x11, 0x46, 0x81, 0xFE,
	NULL, NULL, 0x00, 0x00, 0x75, 0xCA, 0x5F, 0x5E, 0x33, 0xC0, 0x5B, 0xC2, 0x04, 0x00, 0x5F, 0x5E,
	0xB8, 0x01, 0x00, 0x00, 0x00, 0x5B, 0xC2, 0x04, 0x00
};

unsigned char NickLength_Addresses[MAX_NICKNAME_LENGTH_ADRESSES] =
{
	/*
		// 0.3C R5
		3C 03 0F 82 93 01 00 00 3C 14

		// 0.3.7-R2-1
		3C 03 0F 82 E0 01 00 00 3C 14
	*/

	// There is one byte, which another in some SA:MP versions.
	// That's why we set it to NULL. And in 'CheckMemmory' function we set include_null = false;

	0x3C, 0x03, 0x0F, 0x82, NULL, 0x01, 0x00, 0x00, 0x3C, 0x14
};

#else // Linux

#include					<sys/mman.h>
#include					<unistd.h>
#include					<string.h> // for strlen function

#define MEMORY_START					0x804B430
#define MAX_VALID_NICKNAME_ADRESSES		0x75
#define MAX_REPEATED_NICKS_ADRESSES		0x6D
#define MAX_NICKNAME_LENGTH_ADRESSES	0x06

#define DWORD				unsigned long
#define BYTE				unsigned char

#define __cdecl __attribute__((__cdecl__)) // for HOOK_RepeatedNicks

#define PAGESIZE			4096
#define MAX_PATH			260

unsigned char ValidNickName_Addresses[MAX_VALID_NICKNAME_ADRESSES] =
{
	0x55, 0x89, 0xE5, 0x53, 0x8B, 0x5D, 0x08, 0x0F, 0xB6, 0x0B, 0x84, 0xC9, 0x74, 0x5A, 0x66, 0x90,
	0x88, 0xC8, 0x2C, 0x30, 0x3C, 0x09, 0x88, 0xC8, 0x0F, 0x96, 0xC2, 0x2C, 0x41, 0x3C, 0x19, 0x0F,
	0x96, 0xC0, 0x08, 0xC2, 0x75, 0x3A, 0x88, 0xC8, 0x2C, 0x61, 0x3C, 0x19, 0x76, 0x32, 0x80, 0xF9,
	0x5D, 0x74, 0x2D, 0x80, 0xF9, 0x5B, 0x74, 0x28, 0x80, 0xF9, 0x5F, 0x74, 0x23, 0x80, 0xF9, 0x24,
	0x74, 0x1E, 0x80, 0xF9, 0x3D, 0x74, 0x19, 0x80, 0xF9, 0x28, 0x74, 0x14, 0x80, 0xF9, 0x29, 0x74,
	0x0F, 0x80, 0xF9, 0x40, 0x74, 0x0A, 0x80, 0xF9, 0x2E, 0x75, 0x12, 0x90, 0x8D, 0x74, 0x26, 0x00,
	0x43, 0x0F, 0xB6, 0x0B, 0x84, 0xC9, 0x75, 0xA8, 0x5B, 0x31, 0xC0, 0x5D, 0xC3, 0x5B, 0xB8, 0x01,
	0x00, 0x00, 0x00, 0x5D, 0xC3
};
	
unsigned char RepeatedNicks_Addresses[MAX_REPEATED_NICKS_ADRESSES] =
{
	/*
		// 0.3C R5
		55 89 E5 57 56 53 83 EC  0C 31 DB 8B 75 08 8B 7D
		0C EB 09 43 81 FB F4 01  00 00 74 46 0F B7 C3 66
		3D F3 01 77 EE 8B 94 86  68 EA 00 00 85 D2 74 E3
		31 D2 66 3D F3 01 77 0D  8D 04 80 8D 04 80 8D 94
		30 08 FA 00 00 89 7C 24  04 89 14 24 E8 E3 D6 FA
		FF 85 C0 75 BE 83 C4 0C  B8 01 00 00 00 5B 5E 5F
		5D C3 83 C4 0C 31 C0 5B  5E 5F 5D C3 8D

		// 0.3.7-R2-1
		55 89 E5 57 56 53 83 EC  0C 31 DB 8B 75 08 8B 7D
		0C EB 09 43 81 FB E8 03  00 00 74 46 0F B7 C3 66
		3D E7 03 77 EE 8B 94 86  FC 49 02 00 85 D2 74 E3
		31 D2 66 3D E7 03 77 0D  8D 04 80 8D 04 80 8D 94
		30 3C 69 02 00 89 7C 24  04 89 14 24 E8 8B 9B F7
		FF 85 C0 75 BE B8 01 00  00 00 83 C4 0C 5B 5E 5F
		5D C3 31 C0 EB F4 8D
	*/

	0x55, 0x89, 0xE5, 0x57, 0x56, 0x53, 0x83, 0xEC, 0x0C, 0x31, 0xDB, 0x8B, 0x75, 0x08, 0x8B, 0x7D,
	0x0C, 0xEB, 0x09, 0x43, 0x81, 0xFB, NULL, NULL, 0x00, 0x00, 0x74, 0x46, 0x0F, 0xB7, 0xC3, 0x66,
	0x3D, NULL, NULL, 0x77, 0xEE, 0x8B, 0x94, 0x86, NULL, NULL, NULL, 0x00, 0x85, 0xD2, 0x74, 0xE3,
	0x31, 0xD2, 0x66, 0x3D, NULL, NULL, 0x77, 0x0D, 0x8D, 0x04, 0x80, 0x8D, 0x04, 0x80, 0x8D, 0x94,
	0x30, NULL, NULL, NULL, 0x00, 0x89, 0x7C, 0x24, 0x04, 0x89, 0x14, 0x24, 0xE8, NULL, NULL, NULL,
	0xFF, 0x85, 0xC0, 0x75, 0xBE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0x5B, 0x5E, 0x5F,
	0x5D, 0xC3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};

unsigned char NickLength_Addresses[MAX_NICKNAME_LENGTH_ADRESSES] =
{
	/*
		// 0.3C R5
		3C 02 76 04 3C 14

		// 0.3.7-R2-1
		3C 02 76 BF 3C 14
		
	*/
	// There is one byte, which another in some SA:MP versions.
	// That's why we set it to NULL. And in 'CheckMemmory' function we set include_null = false;
	0x3C, 0x02, 0x76, NULL, 0x3C, 0x14
};
#endif